<template>
  <div style="width: 100%; height: 100%; overflow: auto" class="u-core-index">
    <ARow type="flex" style="margin: 8px 8px 16px" class="u-row">
      <ACol flex="1 1 268px">
        <div class="u-col-statistic">
          <Statistic title="当前在线人数" :value="currentOnlineDto.currentOnline" />
        </div>
      </ACol>
      <ACol flex="1 1 268px">
        <div class="u-col-statistic">
          <Statistic title="当天访问人数" :value="currentOnlineDto.todayAccess"/>
        </div>
      </ACol>
      <ACol flex="1 1 268px">
        <div class="u-col-statistic">
          <Statistic title="设备总数 / 在线数" :value="currentDeviceDto.today">
            <template #suffix>
              <span>/ {{currentDeviceDto.online}}</span>
            </template>
          </Statistic>
        </div>
      </ACol>
    </ARow>
    <ACard title="物联网服务概况" class="u-row" size="small">
      <ARow type="flex" class="u-row">
        <ACol flex="50%">
          <div id="iot-server" style="height: 280px"></div>
        </ACol>
        <ACol flex="50%">
          <ATable :columns="ComponentColumns" :data-source="serverComponents" :pagination="false" :showHeader="false">
            <template #title>
              <div style="text-align: center; font-size: 18px">
                <span>各socket服务详情</span>
              </div>
            </template>
          </ATable>
        </ACol>
      </ARow>
    </ACard>
    <ACard title="服务器概况" class="u-row" size="small">
      <ARow type="flex" class="u-row">
        <ACol flex="50%">
          <div id="iot-system-pm" style="width: 100%; height: 200px"></div>
          <a-card class="iot-system-profile">
            <a-card-grid style="width: 50%; text-align: center">
              操作系统：{{systemHealth.os}}
            </a-card-grid>
            <a-card-grid style="width: 50%; text-align: center">
              CPU架构：{{systemHealth.arch}}
            </a-card-grid>
            <a-card-grid style="width: 50%; text-align: center">
              总内存：{{systemHealth.totalPMSize}}(MB)
            </a-card-grid>
            <a-card-grid style="width: 50%; text-align: center">
              可用内存：{{systemHealth.freePMSize}}(MB)
            </a-card-grid>
          </a-card>
        </ACol>
        <ACol flex="50%">
          <div id="iot-system-cpu" style="width: 100%; height: 290px"></div>
        </ACol>
      </ARow>
    </ACard>
  </div>
</template>
<!--首页或者工作台-->
<script lang="ts" name="iot-index" setup>
  import * as echarts from 'echarts/core'
  import {LineChart, PieChart} from 'echarts/charts';
  import {CanvasRenderer} from 'echarts/renderers';
  import {UniversalTransition} from 'echarts/features';
  import {
    ToolboxComponent,
    DatasetComponent,
    GridComponent,
    LegendComponent,
    TitleComponent,
    TooltipComponent,
    VisualMapComponent
  } from 'echarts/components'
  import { Statistic } from 'ant-design-vue';
  import {onMounted, onUnmounted, onActivated, onDeactivated, ref} from "vue";
  import {HealthWebsocket} from "../debug/debugUtils";
  import {getOnline, getDeviceStatistics} from "./index.api";
  import dayjs from "dayjs";
  import { useMessage } from '/@/hooks/web/useMessage';

  const { createMessage } = useMessage();

  echarts.use([CanvasRenderer, TitleComponent, GridComponent, VisualMapComponent, LineChart
    , UniversalTransition, TooltipComponent, PieChart, LegendComponent, DatasetComponent, ToolboxComponent])

  const cpuCharts = ref(); // cpu使用率图表
  const pmCharts = ref(); // 内存使用饼状图表
  const componentCharts = ref(); // 服务器监听的端口信息图表

  let cpuValueList : any = [];
  let ComponentColumns = ref([
    {title: '组件', dataIndex: 'name', key: 'name'},
    {title: '端口', dataIndex: 'port', key: 'port'},
    {title: '协议', dataIndex: 'protocol', key: 'protocol'},
  ]);
  let serverHealth = ref({components: 0, tcpLinks: 0});
  let systemHealth = ref({os: '', arch: '', totalPMSize: '0', freePMSize: '0', version: ''});
  let componentHealth = ref([]);

  let healthWs = new HealthWebsocket('system', (data) => {
    let {os, arch, version, totalPMSize, freePMSize} = data;
    systemHealth.value.os = os;
    systemHealth.value.arch = arch;
    systemHealth.value.version = version;

    let date = dayjs().format('HH:mm:ss');
    let freeUse = (freePMSize / 1024 / 1024).toFixed(0); // 未使用
    let usedSize= ((totalPMSize - freePMSize) / 1024 / 1024).toFixed(0) // 已使用内存

    systemHealth.value.freePMSize = freeUse;
    systemHealth.value.totalPMSize = (totalPMSize / 1024 / 1024).toFixed(0);
    if(cpuValueList.length > 100) {
      cpuValueList.splice(0, 1);
    }

    cpuValueList.push({value: data['systemCpuLoad'].toFixed(2), time: date})

    cpuCharts.value.setOption({
      series: [{
          data: cpuValueList.map(item => item['value'])
        }
      ],
      xAxis: [
        {
          data: cpuValueList.map(item => item['time'])
        }
      ],
    });

    pmCharts.value.setOption({
      series: [{
        data: [
          { value: usedSize, name: `已使用` },
          { value: freeUse, name: `未使用` },
        ]
      }],
    })
  });

  // 获取物联网启用监听的tcp信息
  let serverComponents: any = ref([]);
  let source: any = [], series: any = [], times: any = [];
  let serverWs = new HealthWebsocket('server', ({components}) => {
    times.push(dayjs().format('HH:mm:ss'))
    if(serverComponents.value.length != components.length) {
      serverComponents.value = components;
    }

    if(source.length != components.length) {
      source = components.map(item => item['name']);
    }

    if(series.length != components.length) {
      components.forEach(item => {
        series.push({name: item['name'], type: 'line', stack: 'total', data: [item['linkingCount']]})
      })
    }
    if(cpuValueList.length > 100) {
      cpuValueList.splice(0, 1);
    }
    if(times.length > 100) {
      times.splice(0, 1);
    }
    components.forEach((item, index) => {
      let value = series[index];
      if(value) {
        if(value['data'].length > 100) {
          value['data'].splice(0, 1);
        }
        value['data'].push(item['linkingCount']);
      }
    })

    componentCharts.value.setOption({
      xAxis: {
        data: times
      },
      legend: {
        data: source
      },
      series: series,
    })
  })

  const currentDeviceDto :any = ref({online: 0, today: 0})
  const currentOnlineDto :any = ref({currentOnline: 0, todayAccess: 0})

  loadOnline();
  loadDeviceStatistics();
  
  onMounted(() => {
    let valueList = cpuValueList;
    cpuCharts.value = echarts.init(document.getElementById("iot-system-cpu"));
    cpuCharts.value.setOption({
      title: {
        text: 'CPU使用率(%)',
        left: 'center',
      },
      visualMap: [
        {
          show: false,
          type: 'continuous',
          seriesIndex: 0,
          min: 0,
          max: 1
        }
      ],
      tooltip: {
        trigger: 'axis'
      },
      xAxis: [
        {
          data: valueList
        }
      ],
      yAxis: [
        {},
      ],
      grid: [
        {
          bottom: '20px'
        },
        {
          top: '0px'
        }
      ],
      series: [
        {
          type: 'line',
          showSymbol: true,
          data: valueList
        },
      ]
    });
    pmCharts.value = echarts.init(document.getElementById("iot-system-pm"));
    pmCharts.value.setOption({
      title: {
        text: '内存使用占比',
        left: 'center'
      },
      tooltip: {
        trigger: 'item'
      },
      legend: {
        orient: 'vertical',
        left: 'left'
      },
      series: [
        {
          type: 'pie',
          radius: '50%',
          data: [
            { value: 0, name: '已使用' },
            { value: 0, name: '未使用' },
          ],
          avoidLabelOverlap: false,
          label: {
            //echarts饼图内部显示百分比设置
            show: true,
            position: "outside", //outside 外部显示  inside 内部显示
            formatter: `{d}%`,
            color: "#424141", //颜色
            fontSize: 12 //字体大小
          },
          emphasis: {
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)'
            }
          }
        }
      ]
    })

    componentCharts.value = echarts.init(document.getElementById("iot-server"));
    componentCharts.value.setOption({
      title: {
        text: 'tcp连接数',
        // left: 'center'
      },
      tooltip: {
        trigger: 'axis',
      },
      legend: {
        data: []
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '0%',
        containLabel: true
      },
      toolbox: {
        feature: {
          saveAsImage: {}
        }
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
      },
      yAxis: {
        type: 'value'
      },
      series: []
    });
    healthWs.interval(1500); // 1.5秒钟采集一次
    serverWs.interval(3000); // 3秒一次
  });

  async function loadOnline(){
    const res = await getOnline({});
    if(res){
      currentOnlineDto.value = res;
    }
  }

  async function loadDeviceStatistics(){
    const res = await getDeviceStatistics({});
    if(res){
      currentDeviceDto.value = res;
    }
  }

  onActivated(()=>{
    //进入页面开启
    healthWs.start();
    serverWs.start();
  });

  onDeactivated(()=>{
    //离开页面暂停
    healthWs.suspend();
    serverWs.suspend();
  });

  onUnmounted(() => {
    //销毁关闭
    healthWs.stop();
    serverWs.stop();
  });

</script>

<style lang="less" scoped>
.u-core-index {

}
.u-row {
  margin: 8px 8px 16px;
}
.u-col-statistic {
  width: 228px;
  padding: 16px;
  text-align: center;
  background: #ffffff;
}
.iot-system-profile .ant-card-grid {
  padding: 8px;
}
</style>
